# Развертывание

DocHub поддерживает следующие режимы развертывания:

1. **Plugin** - Плагин IDE (Idea / VSCode). Вся бизнес-логика располагается в плагине;
2. **Server Less** - Портал. Вся бизнес-логика располагается на клиенте.
3. **Client-Server** - Портал. Основная бизнес-логика располагается на сервере.
4. **Cluster** - Ноды в режиме **Client-Server** функционируют в кластере.

Режимы имеют свои преимущества и недостатки. Необходимо их рассмотреть детально:

## Plugin

Самый простой режим. 

Установите плагин из магазина приложений [intellij idea](https://plugins.jetbrains.com/plugin/18518-dochub-architecture-as-code). 
Следуйте подсказкам плагина.

Вам также поможет статья ["Архитектура рядом с кодом"](https://habr.com/ru/post/659595/).

### Преимущества
1. Развертывание буквально за 2 минуты;
2. Встраивание в инструмент производства (IDE);
3. Интерактивное отображение воздействия на код архитектуры;
4. Разметка кода проекта на объекты архитектурного учета и интерактивное взаимодействие с разметкой;
5. Полноценная функциональность.

### Недостатки
1. Монопольный режим, актуальный для развития (внесения изменений) в код архитектуры.

### Рекомендации

Прекрасно подходит для изучения инструмента. 

Остается востребованным на всех этапах внедрения DocHub в организации, т.к. позволяет внедрить подход
"Архитектура как код" в ключевой этап производства - разработку кодовой базы приложений, сервисов 
и инфраструктуры. 


## Server Less

[Проект](https://github.com/RabotaRu/DocHub) собирается как обычный статический сайт командой:

```
  npm run build
```

В папку ./dist генерируется комплект файлов, который является DocHub WEB-приложением. 
Подробнее о сборке и развертывании смотри [здесь](https://github.com/RabotaRu/DocHub). 

Файлы содержащие код архитектуры загружаются по доступным приложению URL при его исполнении в браузере.

Проще говоря, если вы развернули сайт на http://www.dochub.local, необходимо указать в переменной
окружения корневой манифест, например:

```
VUE_APP_DOCHUB_ROOT_MANIFEST=workspace/service/root.yaml
```

в этом случае, сразу после загрузки приложения в браузере, DocHub попытается загрузить файл 
http://www.dochub.local/workspace/service/root.yaml и "выполнить" его. В корневом манифесте могут 
содержаться указания по подключению зависимостей. Например:

```yaml
imports:
  - docs/root.yaml
  - rules/root.yaml
  - plugins/root.yaml
...
```

Эти файлы также будут загружены.

Базовым URL для них будет URL файла "workspace/service/root.yaml". 
Например, для "docs/root.yaml" прямой URL будет - http://www.dochub.local/workspace/service/docs/root.yaml

Подключаемые файлы также могут содержать команды подключения других файлов. В таком случае цикл повторяется.

Таким образом **на клиенте** собирается полная кодовая база архитектуры. 

Вся бизнес-логика выполняется на клиенте.

### Преимущества
1. Минимальное количество серверных ресурсов;
2. Минимальное время на разворачивание и конфигурирование (почти все параметры можно оставить по умолчанию);
3. При интеграции с GitLab позволяет разделять доступы пользователей на уровне репозиториев.

### Недостатки
1. При росте кодовой базы возникает заметная деградация производительности клиентского приложения;
2. Не позволяет разделять доступ пользователей на уровне объектов архитектурного учета;
3. Не предлагает специального интерфейса интеграции (API), что затрудняет переиспользование архитектурных объектов 
   для производственных нужд. 

### Рекомендации

Данный режим оптимален для изучения инструмента и опытной эксплуатации. С ростом кодовой базы и потребностей,
рекомендуется мигрировать в режим "Client-Server".


## Client-Server

В этом режиме основная бизнес-логика DocHub исполняется на сервере. К ней относится (но не ограничивается):

1. Загрузка и сборка кодовой базы архитектуры;
2. Выполнение JSONata запросов к данным архитектуры;
3. Кэширование результатов выполнения JSONata запросов;
4. Контроль доступа к архитектурным артефактам (файлы различного назначения) (в разработке);
5. Разграничение прав доступа к объектам архитектурного учета (в разработке).

Отельно необходимо отметить, что сервер DocHub предоставляет API:

1. **/core/storage/jsonata/:query** - Доступ к кодовой базе (архитектурному Data Lake) через JSONata запросы;
2. **/core/storage/validators/** - Доступ к результату работы [валидаторов](/docs/dochub.rules.validators);
2. **/entities/:entity/presentations/:presentation*** - Доступ к презентациям 
   [сущностей](/docs/dochub.entities) специального типа "upload".

Простейшей сборкой DocHub в режиме Client-Server является команда:

```
  npm run backend
```

При ее выполнении будет собран frontend и запущен backend процесс nodejs в соответствии с конфигурацией среды (см.
[example.env](https://github.com/RabotaRu/DocHub/blob/master/example.env)).

### Преимущества
1. Заметно ускоряет работу пользовательского приложения за счет единоразовой подготовки архитектурной 
   кодовой базы на стороне backend;
2. Позволяет кэшировать результаты запросов и разделять кэши между пользователями, что значительно
   сокращает отклик приложения на действия пользователя;
3. Позволяет регулировать доступ пользователя к объектам архитектурного учета (в разработке);
4. Скрывает для пользователя чувствительные конфигурационные денные интеграций, например с хранилищами GitLab;
5. Предоставляет API для встраивания DocHub в DevOps процессы.

### Недостатки
1. Требует более сложной конфигурации как самого DocHub так и серверных ресурсов для 
   стабильного функционирования;
2. При сложных связях архитектурного кода, могут потребоваться специальные меры по инвалидации
   кэша (регулярно чистить кэш);
3. Перезапуск сервера, при значительных объемах кодовой базы может занимать заметное время,
   что воздействует на всех пользователей.


### Рекомендации

Данный режим разумно использовать при существенных объемах кодовой базы и использовании DocHub 
как инструмента встраиваемого в процессы производства (в DevOps процессы в частности). 


## Cluster 

**ВНИМАНИЕ!** Данный режим проходит beta-тестирование.

Этот режим создан для того, чтобы сервис DocHub был доступен в любое время. В кластере может быть запущено много нод
в режиме "Client-Server", что обеспечивает доступ к сервису, даже если все, кроме одной ноды, вышли из строя.

Также режим позволяет обновлять данные манифестов без приостановки работы сервиса.

Функционирование кластера обеспечивается синхронизацией нод через СУБД [Redis](https://redis.io/).

### Компонентная схема работы кластера

```plantuml
@startuml
  actor "User" as user
  component "Browser" as browser
  component "Balancer" as balancer


  package "DocHub кластер" {
    component "Node 1" as node1
    component "Node 2" as node2
    component "Node N" as nodeN
  }

  database "Redis" as redis
  database "Хранилище\nманифестов" as storage

  user <-D- browser
  browser <-D- balancer

  redis <-U-> node1
  redis <-U-> node2
  redis <-U-> nodeN

  storage -U-> node1
  storage -U-> node2
  storage -U-> nodeN

  balancer <-D- node1
  balancer <-D- node2
  balancer <-D- nodeN
@enduml
```

### Алгоритм работы кластера 
```plantuml
@startuml
participant DocHubFront [
    =DocHub
    ----
    ""Front end""
]

participant Balancer [
    =Balancer
    ----
    ""Балансировщик""
]

participant DocHubNode1 [
    =DocHub
    ----
    ""Server node1""
]

participant DocHubNode2 [
    =DocHub
    ----
    ""Server node2""
]


participant Storage [
    =Storage
    ----
    ""Хранилище""
    ""манифестов""
]

participant Redis [
    =Redis
    ----
    ""Медиатор""
    ""кластера""
]

group Старт или перезагрузка ноды Server node1
 DocHubFront -> Balancer: Запрос
 Balancer -> DocHubNode1: Попытка запроса

 note over of DocHubNode1: Пока нода не готова, она будет отдавать на запросы код 503
 Balancer <- DocHubNode1: 503 временно недоступно
 Balancer -> Balancer: Переключение на другую ноду
 Balancer -> DocHubNode2: Попытка запроса
 Balancer <- DocHubNode2: 200 результат
 DocHubFront <- Balancer: Результат

 DocHubNode1 <-Storage: Загрузка манифестов
 DocHubNode1 -> DocHubNode1: Вычисление HASH состояния
 DocHubNode1 -> Redis: Запись HASH по ключу DocHub.cluster.hash
 note over of DocHubNode1: По завершению загрузки нода будет отвечать с кодом 200
end

group Синхронизация Server node2
 DocHubFront -> Balancer: Запрос
 Balancer -> DocHubNode2: Попытка запроса
 DocHubNode2 <- Redis:  Получение HASH 
 note right of DocHubNode2: При каждом запросе к ноде она\n сверяет локальный HASH состояния с Redis
 DocHubNode2 <- DocHubNode2: Сверка HASH
 DocHubNode2 <- DocHubNode2: Обнаружено расхождение
 note right of DocHubNode2: При обнаружении расхождения,\nзапускается процесс обновления данных манифестов\nОтдается ответ 503
 Balancer <- DocHubNode2: 503 временно недоступно

 Balancer -> Balancer: Переключение на другую ноду
 Balancer -> DocHubNode1: Попытка запроса
 Balancer <- DocHubNode1: 200 результат
 DocHubFront <- Balancer: Результат

 DocHubNode2 <-Storage: Загрузка манифестов
 DocHubNode2 -> DocHubNode2: Вычисление HASH состояния
 DocHubNode2 -> Redis: Запись HASH по ключу DocHub.cluster.hash
 note over of DocHubNode2: По завершению загрузки нода будет отвечать с кодом 200

end


@enduml

```

### Преимущества
1. Предоставляет все преимущества развертывания в режиме Client-Server;
2. Обеспечивает высокую надежность сервиса и дополнительное повышение производительности за 
   счет горизонтального масштабирования;
3. Обеспечивает работу сервиса без простоя в период обновления данных.

### Недостатки
1. Требует развертывания инфраструктуры отказоустойчивости: балансировщик, Redis;
2. При сложных связях архитектурного кода, могут потребоваться специальные меры по инвалидации
   кэша (регулярно чистить кэш).


### Рекомендации

Кластер рекомендуется применять при высоких требованиях к уровню сервиса по надежности и производительности. 

### Конфигурирование

Для перевода группы серверов в режиме Client-Server в кластер, необходимо:

1. Развернуть СУБД [Redis](https://redis.io/);
2. Развернуть балансировщик и настроить его. Например, можно использовать
   [nginx](https://nginx.org/ru/docs/http/ngx_http_upstream_module.html) ;
3. Добавить в конфигурацию серверов параметры:

```
# Формат URL подключения: redis[s]://[[username][:password]@][host][:port][/db-number]
VUE_APP_DOCHUB_REDIS_URL=redis://alice:foobared@awesome.redis.server:6380
VUE_APP_DOCHUB_CLUSTER=on
```
4. Перезапустить серверы.


## Файлы переменных среды исполнения

Файлы конфигурации среды исполнения:
```text
.env                # загружается во всех случаях
.env.local          # загружается во всех случаях, игнорируется git
.env.[mode]         # загружается только в указанном режиме работы
.env.[mode].local   # загружается только в указанном режиме работы, игнорируется git
```
[Больше информации](https://cli.vuejs.org/ru/guide/mode-and-env.html) 

## Переменные среды исполнения и примеры конфигураций

Актуальные параметры конфигурирования смотрите в файле
[example.env](https://github.com/RabotaRu/DocHub/blob/master/example.env)
